package encoder

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	message2 "zinxtcp/default/message"
	"zinxtcp/ziface"
)

type Encoder struct{}

func (e *Encoder) GetPackFunc() func(ziface.IHeader, []byte) ([]byte, error) {
	return Pack
}

func (e *Encoder) GetUnpackFunc() func(*net.TCPConn) (ziface.IMessage, error) {
	return UnPacket
}

func Pack(header ziface.IHeader, data []byte) ([]byte, error) {
	if header.GetMsgType() == 0 {
		return nil, errors.New("the message id on header could not be zero.")
	}
	if header.GetDataLen() == 0 {
		header.SetDataLen(uint32(len(data)))
	}
	headerByte, err := header.EncodeHeader()
	if err != nil {
		return nil, err
	}
	dataBuff := bytes.NewBuffer(headerByte)
	//写data数据
	if err := binary.Write(dataBuff, binary.LittleEndian, data); err != nil {
		return nil, err
	}
	return dataBuff.Bytes(), nil
}

func UnPacket(c *net.TCPConn) (ziface.IMessage, error) {
	message := &message2.Message{}
	headData := make([]byte, message.GetHeadLen())
	if _, err := io.ReadFull(c, headData); err != nil {
		fmt.Println("read msg head error ", err)
		return nil, err
	}
	if err := message.ParseHeader(headData); err != nil {
		fmt.Println("parse msg head error ", err)
		return nil, err
	}
	var data []byte
	if message.GetDataLen() > 0 {
		data = make([]byte, message.GetDataLen())
		if _, err := io.ReadFull(c, data); err != nil {
			fmt.Println("read msg data error ", err)
			//c.ExitBuffChan <- true
			return nil, err
		}
	}
	message.SetData(data)
	return message, nil
}
